package com.littleindian.radioskypipeviewer;

import java.io.BufferedInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.androidplot.xy.XYPlot;
import com.androidplot.ui.AnchorPosition;
import com.androidplot.ui.widget.Widget;
import com.androidplot.xy.BoundaryMode;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.LineAndPointRenderer;
import com.androidplot.xy.XLayoutStyle;
import com.androidplot.xy.YLayoutStyle;
import android.graphics.Color;

public class Viewer extends Activity implements Runnable{
	public static String TAG = "RadioSkypipeViewer";
	private static String TAG1 = "Viewer: ";
	
	private static int SIZE_BUFFER = 64;
	
	private RSPStreamProcessor mStreamProc = new RSPStreamProcessor(SIZE_BUFFER*2);
    private ArrayList<Point> mPoints;
	private Thread mProcessThread;
	private Context mContext;
	
	private TextView mTemperatureView;
    private TextView mTemperatureAvgView;
	private Button mBtnListen;

    private XYPlot mPlot;
    private SimpleXYSeries mDataSeries;
    private LineAndPointFormatter mFormatter;
    
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        setContentView(com.littleindian.radioskypipeviewer.R.layout.main);
     
        mContext = this;
        mTemperatureView = (TextView)findViewById(R.id.current_temperature);
        mTemperatureView.setTextSize(20);
        
        mTemperatureAvgView = (TextView)findViewById(R.id.avg_temperature);
        mTemperatureAvgView.setTextSize(20);
        
        mBtnListen = (Button)findViewById(R.id.listen);
        mBtnListen.setOnClickListener(new View.OnClickListener(){
			public void onClick(View v) {
				mProcessThread = null;
				mProcessThread = new Thread((Runnable) mContext);
				mProcessThread.start();
			}
        });
        
        setupPlot();
        
    }
    
    private void setupPlot() {
        // initialize our XYPlot reference:
        mPlot = (XYPlot) findViewById(R.id.xyplot);
        
        // add a new series
        mDataSeries = new SimpleXYSeries(100);
        mFormatter = new LineAndPointFormatter(Color.rgb(0, 200, 0),
				  Color.rgb(200, 0, 0), 
				  Color.rgb(0, 0, 200));

        mPlot.addSeries(mDataSeries, LineAndPointRenderer.class, mFormatter);

        // reduce the number of range labels
        mPlot.getGraphWidget().setRangeTicksPerLabel(4);

        // reposition the domain label to look a little cleaner:
        Widget domainLabelWidget = mPlot.getDomainLabelWidget();

        mPlot.position(domainLabelWidget,                     // the widget to position
                                45,                                    // x position value, in this case 45 pixels
                                XLayoutStyle.ABSOLUTE_FROM_LEFT,       // how the x position value is applied, in this case from the left
                                0,                                     // y position value
                                YLayoutStyle.ABSOLUTE_FROM_BOTTOM,     // how the y position is applied, in this case from the bottom
                                AnchorPosition.LEFT_BOTTOM);           // point to use as the origin of the widget being positioned

        // get rid of the visual aids for positioning:
        mPlot.disableAllMarkup();
        
        mPlot.setTitle("Lyle Radio Observatory");
        mPlot.setRangeLabel("Temperature [deg K]");
        mPlot.setDomainLabel("Time [UTC]");
    }
    
    private float[] mTemperatures = new float[10];
    private boolean mAvgFull = false;
    private int mAvgPos = 0;
    private Handler mDataHandler = new Handler() {
    	@Override
    	public void handleMessage(Message msg) {
    		try {
	    	    if(mPoints != null ) {
	        	    if( mPoints.size() > 0 ) {
	        	    	
	        	    	for(int i=0; i<mPoints.size(); ++i) {
		        	    	if( mPoints.get(i) != null) {
		        	    		
		        	    		int iTemperature = (int)(mPoints.get(i).y/1000);
		        	    		float fSignal = (float)(mPoints.get(i).y/1000);
		        	    		float fTime = (float)(mPoints.get(i).x/1000000);
		        	    		
		        	    		//mDataSeries.addValue(iTemperature);
		        	    		mDataSeries.addValue(fTime, fSignal);
		        	    		
		        	            //mPlot.addSeries(mDataSeries, LineAndPointRenderer.class, mFormatter);
		        	    		mPlot.postInvalidate();
	
		        	    		float value = (float)(iTemperature);
		        	    		mTemperatureView.setText(Integer.toString((int)value));
		        	    		mTemperatures[mAvgPos] = value;
		        	    		mAvgPos++;
		        	    		if(mAvgPos >= mTemperatures.length) {
		        	    			mAvgPos = 0;
		        	    			float avg = 0;
		            	    		for(int j=0; j<mTemperatures.length; ++j)
		            	    			avg += mTemperatures[j];
		            	    		avg /= mTemperatures.length;
		            	    		Log.w(TAG,"average "+avg);
		            	            mTemperatureAvgView.setText(Integer.toString((int)avg));
		        	    		}
		        	    	}
	        	    	}
	        	    }
		    	}
		    }
		    catch(Exception e) {
		    	Log.e(TAG,e.toString(), e);
		    }
    	};
    };

    public void run() {
        	while(true) {
                try {

                	// Grab the server URL 
                	EditText serverAddress = (EditText)findViewById(R.id.server_address);
                	String strURL = "http://" + serverAddress.getText() + ":6300";
		        	Log.d(TAG, TAG1+"launching Skipipe Viewer at "+strURL);
		        	
		        	// Setup an conntection to the server
		        	//URL url = new URL("http://66.228.18.165:6300");
		        	URL url = new URL(strURL);
		        	HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
		        	urlConnection.connect();
		        	
		        	// Grab the input stream from the server
		        	InputStream in = new BufferedInputStream(urlConnection.getInputStream());
		            byte[] ba = new byte[SIZE_BUFFER];
		            
		            // Loop through data from the server.
		            int count = 0;
		        	while(true) { 
		        		// Grab the next chunk of server data
		        		//Log.d(TAG, new String(ba));
		        		int n;
		        		if( (n = in.read(ba))==-1) {
		        			Log.d(TAG,"in.read == -1, count="+count);
		        			break;
		        		}
		        		// Process the data chunk
		        		mPoints = mStreamProc.processBuffer(ba, n);
		        		
		        		// Post an update message to the UI thread.
		        		if( mPoints.size() > 0 )
		        			mDataHandler.sendEmptyMessage(0);
		        		count += mPoints.size();
		        	}
		          
		        	// Something went wrong.  The RSP server should stream data 
		        	// (but it doesn't without hand holding which we are not sure how to do yet.
		        	//  we have bailed from the server processing loop.  probably lost the input stream).
		        	// - setup for a reconnect.
		        	Log.e(TAG,"DISCONNECTING");
		        	urlConnection.disconnect();
	            } catch (Exception e) { 
	            	Log.e(TAG,e.toString(), e);
	            	try { Thread.sleep(2000); } catch (InterruptedException ie) {}
	            }
        	} // while(true)
    }
}
    
    